#include "transFile.h"
#define BUF_SIZE 1024

int sendFile(const int netfd, const char* filename){
    if(netfd == -1){
        fprintf(stderr, "wrong parameter.\n");
        return -1;
    }
    train_t train;
    int filefd = open(filename, O_RDWR);
    ERROR_CHECK(filefd, -1, "transFile: sendfile open file");

    //char buf[BUF_SIZE] = { 0 };
    int ret = 0;

    // send filename
    train._length = strlen(filename);
    memcpy(train._data, filename, strlen(filename));
    ret = send(netfd, &train, sizeof(train_t) + train._length, MSG_NOSIGNAL);
    ERROR_CHECK(ret, -1, "transFile: send filename");

    // send filesize
    struct stat st;
    ret = fstat(filefd, &st);
    ERROR_CHECK(ret, -1, "transFile: fstat");
    off_t filesize = st.st_size;
    train._length = sizeof(filesize);
    memcpy(train._data, &filesize, sizeof(filesize));
    ret = send(netfd, &train, sizeof(train) + train._length, MSG_NOSIGNAL);
    ERROR_CHECK(ret, -1, "transFile: send filesize");

    // send file
    sendfile(netfd, filefd, NULL, filesize);

    printf("transFile success.\n");

    close(filefd);
    return 0;
}

int recvFile(const int netfd){
    int ret=0;
    //收取文件名
    train_t train;
    char filename[1024]={0};
    ret=recv(netfd,&train._length,sizeof(train._length),MSG_WAITALL);
    ERROR_CHECK(ret,-1,"transFile: recv filename_length ");
    ret=recv(netfd,&train._data,train._length,MSG_WAITALL);
    ERROR_CHECK(ret,-1,"transFile: recv filename");
    memcpy(filename,train._data,train._length);
    int fd=open(filename,O_RDWR|O_CREAT|O_TRUNC,0666);
    ERROR_CHECK(fd,-1,"transFile: recv open file");
    //收取文件长度
    off_t filesize;
    ret=recv(netfd,&train._length,sizeof(train._length),MSG_WAITALL);
    ERROR_CHECK(ret,-1,"transFile: recv filesize_length");
    ret=recv(netfd,&train._data,train._length,MSG_WAITALL);
    ERROR_CHECK(ret,-1,"transFile: recv filesize");
    memcpy(&filesize,train._data,train._length);
    printf("filesize=%ld\n",filesize);

    //收取文件内容
    ftruncate(fd,filesize);
    char *p=(char *)mmap(NULL,filesize,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
    if(p==MAP_FAILED){
        perror("transFile: recv mmap");
        exit(EXIT_FAILURE);
    }
    ret=recv(netfd,p,filesize,MSG_WAITALL);
    ERROR_CHECK(ret,-1,"transFile: recv filecontent");
    ret=munmap(p,filesize);
    if(ret==-1){
        perror("transFile:recv mummap");
        exit(EXIT_FAILURE);
    }
    return 0;
}

int sendMsg(const int netfd, char* buf){
    train_t train;
    int len = strlen(buf) + 1;
    train._length = len;
    memcpy(train._data, buf, len);
    int ret = send(netfd, &train, sizeof(train_t) + train._length, MSG_NOSIGNAL);
    ERROR_CHECK(ret, -1, "sendMsg send");
    return 0;
}

int recvMsg(const int netfd, char* buf){
    train_t train;
    int ret = recv(netfd, &train._length, sizeof(train._length), MSG_WAITALL);
    ERROR_CHECK(ret, -1,"recvMsg recv");
    ret = recv(netfd, train._data, train._length, MSG_WAITALL);
    ERROR_CHECK(ret, -1,"recvMsg recv");
    memcpy(buf, train._data, train._length);
    return 0;
}

